home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-26 | 56.0 KB | 1,337 lines | [TEXT/PJMM] |
- unit Stacks;
-
- interface
-
- uses
- Memory, QuickDraw, Packages, Menus, Events, Fonts, Scrap, ToolUtils,Resources, Errors, Palettes, QDOffscreen, PictUtils, Timer, globals, Utilities, Graphics, Analysis, Camera, file1, file2, filters, sound, lut;
-
- procedure MakeStack;
- procedure MakeWindowsFromStack;
- function AddSlice (update: boolean): boolean;
- procedure DeleteSlice;
- procedure ShowNextSlice (item: integer);
- procedure ShowFirstOrLastSlice (ich: integer);
- procedure DoStackInfo;
- procedure Reslice;
- procedure Animate;
- procedure MakeMovie(ShowDialog: boolean);
- procedure CaptureFrames;
- procedure MakeMontage;
- procedure ConvertRGBToEightBitColor (Capturing: boolean);
- procedure ConvertEightBitColorToRGB;
- procedure CaptureColor;
- procedure AverageSlices;
- procedure ConvertRGBToHSV;
-
-
- implementation
-
-
- procedure MakeStack;
- var
- ok, isStack: boolean;
- i, result: integer;
- TempInfo, SaveInfo: InfoPtr;
- str: str255;
- begin
- if not AllSameSize then begin
- PutError('All currently open images must be the same size to make a stack.');
- exit(MakeStack);
- end;
- isStack := false;
- for i := 1 to nPics do begin
- TempInfo := pointer(WindowPeek(PicWindow[i])^.RefCon);
- isStack := isStack or (TempInfo^.StackInfo <> nil);
- end;
- if isStack then begin
- PutError('All stacks must be closed before making a new stack.');
- exit(MakeStack);
- end;
- if nPics > MaxSlices then begin
- NumToString(MaxSlices, str);
- PutError(concat('Maximun stack size is ', str, ' slices.'));
- exit(MakeStack);
- end;
- StopDigitizing;
- DisableDensitySlice;
- SelectWindow(PicWindow[1]);
- Info := pointer(WindowPeek(PicWindow[1])^.RefCon);
- ActivateWindow;
- KillRoi;
- UnZoom;
- if not MakeStackFromWindow then
- exit(MakeStack);
- with info^ do begin
- StackInfo^.nSlices := nPics;
- title := 'Stack';
- UpdateTitleBar;
- Revertable := false;
- end;
- SaveInfo := Info;
- MakingStack := true;
- ShowWatch;
- for i := 2 to nPics do begin
- TempInfo := pointer(WindowPeek(PicWindow[2])^.RefCon);
- with TempInfo^ do begin
- hunlock(PicBaseHandle);
- info^.StackInfo^.PicBaseH[i] := PicBaseHandle;
- end;
- result := CloseAWindow(PicWindow[2]);
- Info := SaveInfo;
- end;
- UpdateWindowsMenuItem;
- MakingStack := false;
- end;
-
-
- procedure DeleteSlice;
- var
- SliceToDelete, NextSlice, i: integer;
- isRoi: boolean;
- begin
- with info^, info^.StackInfo^ do begin
- if nSlices = 1 then begin
- WhatToUndo := NothingToUndo;
- exit(DeleteSlice);
- end;
- isRoi := RoiShowing;
- if isRoi then
- KillRoi;
- SetupUndo;
- WhatToUndo := UndoSliceDelete;
- SliceToDelete := CurrentSlice;
- if CurrentSlice = 1 then begin
- NextSlice := 2;
- WhatToUndo := UndoFirstSliceDelete;
- end
- else
- NextSlice := CurrentSlice - 1;
- SelectSlice(NextSlice);
- UpdatePicWindow;
- DisposeHandle(PicBaseH[SliceToDelete]);
- for i := SliceToDelete to nSlices - 1 do
- PicBaseH[i] := PicBaseH[i + 1];
- nSlices := nSlices - 1;
- if CurrentSlice <> 1 then
- CurrentSlice := CurrentSlice - 1;
- if (StackType = rgbStack) and (nSlices <> 3) then
- StackType := VolumeStack;
- UpdateTitleBar;
- if isRoi then
- RestoreRoi;
- changes := true;
- UpdateWindowsMenuItem;
- end;
- end;
-
-
- procedure MakeWindowsFromStack;
- var
- i, ignore: integer;
- N: LongInt;
- SaveInfo: InfoPtr;
- tmp: longint;
-
- function MakeName (i: integer): str255;
- var
- str: str255;
- begin
- RealToString(i, 3, 0, str);
- if str[1] = ' ' then
- str[1] := '0';
- if str[2] = ' ' then
- str[2] := '0';
- MakeName := str;
- end;
-
- begin
- N := info^.StackInfo^.nSlices;
- tmp := SizeOf(PicInfo);
- if MaxBlock < (MinFree + info^.ImageSize + (SizeOf(PicInfo) + 2000) * N) then begin
- PutError('There is not enough memory available to convert this stack to windows.');
- exit(MakeWindowsFromStack);
- end;
- SaveInfo := Info;
- KillRoi;
- for i := 1 to N - 1 do begin
- SelectSlice(1);
- info^.StackInfo^.CurrentSlice := 1;
- if not Duplicate(MakeName(i), false) then
- exit(MakeWindowsFromStack);
- info := SaveInfo;
- DeleteSlice;
- end;
- if Duplicate(MakeName(N), false) then begin
- info := SaveInfo;
- info^.changes := false;
- ignore := CloseAWindow(info^.wptr);
- end;
- end;
-
-
- procedure ShowNextSlice (item: integer);
- var
- isRoi: boolean;
- begin
- with info^, info^.StackInfo^ do begin
- if item = NextSliceItem then begin
- CurrentSlice := CurrentSlice + 1;
- if CurrentSlice > nSlices then
- CurrentSlice := nSlices;
- end
- else begin
- CurrentSlice := CurrentSlice - 1;
- if CurrentSlice < 1 then
- CurrentSlice := 1;
- end;
- isRoi := RoiShowing;
- if isRoi then
- KillRoi;
- SelectSlice(CurrentSlice);
- UpdatePicWindow;
- UpdateTitleBar;
- WhatToUndo := NothingToUndo;
- isInsertionPoint:=false;
- if isRoi then
- RestoreRoi;
- end;
- end;
-
-
- procedure ShowFirstOrLastSlice (ich: integer);
- var
- isRoi: boolean;
- begin
- with info^, info^.StackInfo^ do begin
- if ich = EndKey then
- CurrentSlice := nSlices
- else
- CurrentSlice := 1;
- isRoi := RoiShowing;
- if isRoi then
- KillRoi;
- SelectSlice(CurrentSlice);
- UpdatePicWindow;
- UpdateTitleBar;
- WhatToUndo := NothingToUndo;
- isInsertionPoint:=false;
- if isRoi then
- RestoreRoi;
- end;
- end;
-
-
- procedure GetSlice (xstart, ystart, start: extended; angle: extended; count: integer; var line: LineType);
- var
- i: integer;
- x, y, xinc, yinc: extended;
- IntegerStart: boolean;
- begin
- IntegerStart := (xstart = trunc(xstart)) and (ystart = trunc(ystart));
- if IntegerStart and (angle = 0.0) then begin
- GetLine(trunc(xstart), trunc(ystart), count, line);
- exit(GetSlice);
- end;
- if IntegerStart and (angle = 270.0) then begin
- GetColumn(trunc(xstart), trunc(ystart), count, line);
- exit(GetSlice);
- end;
- angle := (angle / 180.0) * pi;
- xinc := cos(angle);
- yinc := -sin(angle);
- x := xstart + start * xinc;
- y := ystart + start * yinc;
- for i := 0 to count - 1 do begin
- line[i] := round(GetInterpolatedPixel(x, y));
- x := x + xinc;
- y := y + yinc;
- end;
- end;
-
-
- function DoResliceOptions: boolean;
- var
- default, tmp: extended;
- Canceled: boolean;
- prompt, str: str255;
- begin
- with info^.StackInfo^, info^ do begin
- if SpatiallyCalibrated then begin
- default := SliceSpacing / xScale;
- str := xUnit;
- end else begin
- default := SliceSpacing;
- str := 'pixels';
- end;
- if SliceSpacing = 0.0 then
- default := 1.0;
- tmp := GetReal(concat('Slice Spacing (', str, '):'), default, 2, Canceled);
- if not Canceled and (tmp > 0.0) then begin
- if SpatiallyCalibrated then
- SliceSpacing := tmp * xScale
- else
- SliceSpacing := tmp;
- end;
- end; {with}
- DoResliceOptions := not canceled;
- end;
-
-
- procedure Reslice;
- var
- DstWidth, DstHeight, nSlices: integer;
- dstLeft, dstTop, y, i, j, LineLength: integer;
- SaveWindowFlag, SaveMacro, HorizontalMode: boolean;
- SaveHScale, SaveVScale, UncalibratedLineLength, CalibratedLineLength, angle: extended;
- Stack, Reconstruction: InfoPtr;
- aLine: LineType;
- name, str1, str2: str255;
- MaskRect: rect;
- x1, y1, x2, y2, ulength, clength: extended;
-
- procedure MakeRoi (Left, Top, Width, Height: integer);
- begin
- with info^ do begin
- RoiType := RectRoi;
- SetRect(RoiRect, left, top, left + width, top + height);
- MakeRegion;
- SetupUndo;
- RoiShowing := true;
- end;
- end;
-
- begin
- with info^, info^.StackInfo^ do begin
- if nSlices < 2 then begin
- PutError('Reslicing requires at least 2 slices.');
- AbortMacro;
- exit(Reslice);
- end;
- if not (RoiShowing and (RoiType = LineRoi)) then begin
- PutError('Please make a straight line selection first.');
- AbortMacro;
- exit(Reslice);
- end;
- Stack := info;
- GetLengthOrPerimeter(ulength, clength);
- LineLength := round(ulength);
- if LineLength = 0 then begin
- PutError('Line length cannot be zero.');
- AbortMacro;
- exit(Reslice);
- end;
- if SliceSpacing = 0.0 then
- if not DoResliceOptions then
-